#include <ctime>
#include <cstdlib>
#include <unistd.h>

#include "RingQueue.hpp"
#include "Task.hpp"

string Selfname()
{
    char name[128];
    snprintf(name,sizeof(name),"thread[0x%x]",pthread_self());
    return name;
}
void* ProductorRoutine(void* args)
{
    // RingQueue<int>* rq = static_cast<RingQueue<int>* >(args);
    RingQueue<Task>* rq = static_cast<RingQueue<Task>* >(args);

    while(true)
    {
        //生产数据
        // int data = rand()%10+1;
        // rq->push(data);
        // cout<< "生产数据： "<< data <<endl;
        //获取或构建任务，是需要花时间的
        int x = rand()%10+1;
        int y = rand()%5;
        char op = oper[rand()%oper.size()];        // int operIdx = rand()%oper.size();
        Task t(x,y,op,mymath);                    // Task t(x,y,oper[operIdx],mymath);

        rq->push(t);
        cout<< Selfname()<<",生产任务："<< t.to_Task_string() <<endl;
        sleep(1);
    }
}
void* consumerRoutine(void* args)
{
    // RingQueue<int>* rq = static_cast<RingQueue<int>* >(args);
    RingQueue<Task>* rq = static_cast<RingQueue<Task>* >(args);

    while(true)
    {
        // int data;
        // rq->pop(&data);
        // cout<< "获取数据: "<< data <<endl;

        //消费或执行任务，是需要花时间的
        Task t;
        rq->pop(&t);
        cout<<Selfname() <<",计算任务："<< t() << endl;
        // sleep(1);
    }
}
//多生产，多消费
int main()
{
    srand((unsigned int)time(nullptr) ^ getpid() ^ 0x1241235);
    RingQueue<Task>* rq = new RingQueue<Task>();

    pthread_t p[5],c[5];
    for(int i = 0;i<5;++i)  pthread_create(p+i,nullptr,ProductorRoutine,rq);
        
    for(int i = 0;i<5;++i)  pthread_create(c+i,nullptr,consumerRoutine,rq);

    for(int i = 0;i<5;++i)  pthread_join(p[i],nullptr);
    for(int i = 0;i<5;++i)  pthread_join(c[i],nullptr);
 
    delete rq;
    return 0;
}
// //单生产，单消费
// int main()
// {
//     srand((unsigned int)time(nullptr) ^ getpid() ^ 0x1241235);
//     RingQueue<Task>* rq = new RingQueue<Task>();
  
//     pthread_t p[5],c[5];
//     pthread_create(&p,nullptr,ProductorRoutine,rq);
//     pthread_create(&c,nullptr,consumerRoutine,rq);

//     pthread_join(p,nullptr);
//     pthread_join(c,nullptr);

 
//     delete rq;

//     return 0;
// }